<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Codeword Puzzle Generator & Interactive Player</title>
    <!-- Tailwind CSS for modern responsive layout & UI -->
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Inter Font */
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
        
        body {
            font-family: 'Inter', sans-serif;
            user-select: none;
        }

        /* Grid styling */
        .puzzle-grid {
            display: grid;
            gap: 1px;
            background-color: #334155;
            border: 2px solid #0f172a;
            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
        }

        .cell {
            position: relative;
            aspect-ratio: 1 / 1;
            background-color: #ffffff;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.15s ease;
        }

        .cell.black-cell {
            background-color: #0f172a;
            cursor: default;
        }

        .cell-number {
            position: absolute;
            top: 2px;
            left: 3px;
            font-size: 0.65rem;
            font-weight: 700;
            color: #475569;
            line-height: 1;
            pointer-events: none;
        }

        .cell-letter {
            font-size: 1.25rem;
            font-weight: 800;
            color: #0f172a;
            text-transform: uppercase;
            pointer-events: none;
        }

        .cell.given .cell-letter {
            color: #1e40af;
        }

        .cell.incorrect .cell-letter {
            color: #dc2626;
        }

        /* Highlights */
        .cell.selected {
            background-color: #fef08a !important; /* Vivid yellow */
            outline: 2px solid #eab308;
            z-index: 10;
        }

        .cell.highlight-same {
            background-color: #fef9c3; /* Light yellow tint for matching numbers */
        }

        /* Print Media Styles */
        @media print {
            body {
                background: white !important;
                color: black !important;
                padding: 0 !important;
                margin: 0 !important;
            }

            .no-print {
                display: none !important;
            }

            .print-only {
                display: block !important;
            }

            .print-page {
                page-break-after: always;
                padding: 1.5cm;
                box-sizing: border-box;
                height: 100vh;
                display: flex;
                flex-direction: column;
                justify-content: space-between;
            }

            .puzzle-grid {
                border: 2px solid #000 !important;
                background-color: #000 !important;
                max-width: 100% !important;
                margin: 0 auto !important;
            }

            .cell {
                background-color: #fff !important;
                border: 0.5px solid #000 !important;
            }

            .cell.black-cell {
                background-color: #000 !important;
            }

            .cell-number {
                color: #000 !important;
                font-size: 0.6rem !important;
            }

            .cell-letter {
                color: #000 !important;
            }

            /* Clear interactive solution entries in print grid unless printing solution */
            .print-puzzle-page .cell:not(.given) .cell-letter {
                display: none !important;
            }

            .key-grid-table {
                width: 100%;
                border-collapse: collapse;
                margin-top: 15px;
            }

            .key-grid-table td, .key-grid-table th {
                border: 1px solid #000;
                text-align: center;
                padding: 6px 2px;
                font-size: 0.8rem;
            }
        }

        .print-only {
            display: none;
        }
    </style>
</head>
<body class="bg-slate-100 text-slate-800 min-h-screen flex flex-col">

    <!-- Header / Controls (Hidden in Print) -->
    <header class="no-print bg-slate-900 text-white shadow-md">
        <div class="max-w-7xl mx-auto px-4 py-4 flex flex-wrap items-center justify-between gap-4">
            <div class="flex items-center space-x-3">
                <div class="bg-indigo-600 p-2 rounded-lg text-white font-bold text-xl tracking-wider">CW</div>
                <div>
                    <h1 class="text-xl font-extrabold tracking-tight">Codeword Puzzle Generator</h1>
                    <p class="text-xs text-slate-400">Cipher Crossword Creator & Interactive Player</p>
                </div>
            </div>

            <!-- Toolbar Controls -->
            <div class="flex flex-wrap items-center gap-3">
                <div class="flex items-center bg-slate-800 rounded-lg p-1 border border-slate-700">
                    <label class="text-xs font-semibold px-2 text-slate-300">Size:</label>
                    <select id="grid-size" class="bg-slate-700 text-white text-xs font-semibold rounded px-2 py-1 outline-none border border-slate-600">
                        <option value="11">11 x 11</option>
                        <option value="13" selected>13 x 13</option>
                        <option value="15">15 x 15</option>
                    </select>
                </div>

                <div class="flex items-center bg-slate-800 rounded-lg p-1 border border-slate-700">
                    <label class="text-xs font-semibold px-2 text-slate-300">Starter Letters:</label>
                    <select id="clue-count" class="bg-slate-700 text-white text-xs font-semibold rounded px-2 py-1 outline-none border border-slate-600">
                        <option value="2">2 Clues</option>
                        <option value="3" selected>3 Clues</option>
                        <option value="4">4 Clues</option>
                    </select>
                </div>

                <button id="btn-generate" class="bg-indigo-600 hover:bg-indigo-500 text-white font-semibold text-xs px-3 py-2 rounded-lg transition shadow flex items-center gap-1">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path></svg>
                    New Puzzle
                </button>

                <button id="btn-print" class="bg-emerald-600 hover:bg-emerald-500 text-white font-semibold text-xs px-3 py-2 rounded-lg transition shadow flex items-center gap-1">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"></path></svg>
                    Print / PDF
                </button>
            </div>
        </div>
    </header>

    <!-- Main App Container -->
    <main class="no-print flex-grow max-w-7xl w-full mx-auto p-4 md:p-6 grid grid-cols-1 lg:grid-cols-3 gap-6">
        
        <!-- Left / Center Column: Grid & Play Controls -->
        <div class="lg:col-span-2 flex flex-col items-center">
            
            <!-- Puzzle Canvas Area -->
            <div class="w-full max-w-[550px] bg-white p-4 rounded-xl shadow-md border border-slate-200">
                <div id="grid-container" class="puzzle-grid w-full"></div>
            </div>

            <!-- In-Game Action Buttons -->
            <div class="flex items-center justify-center gap-3 mt-4 w-full max-w-[550px]">
                <button id="btn-check" class="flex-1 bg-slate-200 hover:bg-slate-300 text-slate-700 font-semibold text-xs py-2 px-3 rounded-lg transition">Check Progress</button>
                <button id="btn-reveal" class="flex-1 bg-slate-200 hover:bg-slate-300 text-slate-700 font-semibold text-xs py-2 px-3 rounded-lg transition">Reveal Solution</button>
                <button id="btn-reset" class="flex-1 bg-slate-200 hover:bg-slate-300 text-slate-700 font-semibold text-xs py-2 px-3 rounded-lg transition">Clear Entries</button>
            </div>
        </div>

        <!-- Right Column: Key Tracking & Alphabet Checklist -->
        <div class="flex flex-col gap-6">
            
            <!-- Number-to-Letter Tracker Box -->
            <div class="bg-white p-5 rounded-xl shadow-md border border-slate-200">
                <h2 class="text-sm font-bold text-slate-800 uppercase tracking-wider mb-3 flex justify-between items-center">
                    <span>Number Key Bar</span>
                    <span id="completion-status" class="text-xs text-indigo-600 font-semibold">0 / 26 solved</span>
                </h2>
                <div id="number-key-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2 text-xs">
                    <!-- Dynamic content generated by JS -->
                </div>
            </div>

            <!-- Alphabet Usage Checklist -->
            <div class="bg-white p-5 rounded-xl shadow-md border border-slate-200">
                <h2 class="text-sm font-bold text-slate-800 uppercase tracking-wider mb-3">Alphabet Reference (A–Z)</h2>
                <div id="alphabet-bar" class="flex flex-wrap gap-1.5">
                    <!-- Dynamic content generated by JS -->
                </div>
            </div>

            <!-- Instructions Card -->
            <div class="bg-indigo-50 border border-indigo-100 p-4 rounded-xl text-xs text-indigo-900 leading-relaxed">
                <h3 class="font-bold mb-1">How to Play:</h3>
                <p>1. Each number from <strong>1 to 26</strong> represents a unique letter of the alphabet.</p>
                <p class="mt-1">2. Click a square and type a letter on your keyboard. All squares sharing that number will update automatically.</p>
                <p class="mt-1">3. Use starter clues and word pattern deduction to uncover the entire puzzle!</p>
            </div>
        </div>
    </main>

    <!-- PRINT ONLY TEMPLATES -->
    <!-- Page 1: Worksheet -->
    <div class="print-only print-page print-puzzle-page">
        <div>
            <div class="flex justify-between items-end border-b-2 border-black pb-2 mb-4">
                <div>
                    <h1 class="text-2xl font-bold uppercase tracking-widest">CODEWORD PUZZLE</h1>
                    <p class="text-xs italic">Each number from 1 to 26 represents a specific letter of the alphabet.</p>
                </div>
                <div class="text-right text-xs">
                    <p>Date: _________________</p>
                    <p class="mt-1">Score: ________________</p>
                </div>
            </div>

            <!-- Print Grid Placement -->
            <div id="print-grid-container" class="my-6"></div>

            <!-- Key Table for Writing -->
            <div class="mt-6">
                <h3 class="text-xs font-bold uppercase mb-1">Code Key Matrix:</h3>
                <table class="key-grid-table" id="print-key-table-1"></table>
            </div>
        </div>

        <div class="text-center text-xs text-slate-500 border-t border-slate-300 pt-2">
            Generated with Codeword Puzzle Generator | www.example.com
        </div>
    </div>

    <!-- Page 2: Solution Page -->
    <div class="print-only print-page">
        <div>
            <div class="border-b-2 border-black pb-2 mb-4">
                <h1 class="text-2xl font-bold uppercase tracking-widest">CODEWORD SOLUTION SHEET</h1>
                <p class="text-xs">Full answer key and code translation table.</p>
            </div>

            <!-- Solution Grid -->
            <div id="print-solution-grid-container" class="my-6"></div>

            <!-- Solution Key Table -->
            <div class="mt-6">
                <h3 class="text-xs font-bold uppercase mb-1">Decoded Answer Key:</h3>
                <table class="key-grid-table" id="print-key-table-2"></table>
            </div>
        </div>

        <div class="text-center text-xs text-slate-500 border-t border-slate-300 pt-2">
            Codeword Puzzle Generator - Answer Sheet
        </div>
    </div>

    <!-- JavaScript Logic -->
    <script>
        // --- BUILT-IN DICTIONARY (Curated English Words) ---
        const DICTIONARY = [
            "ABILITY", "ABLE", "ABOUT", "ABOVE", "ACCEPT", "ACCORD", "ACCOUNT", "ACROSS", "ACTION", "ACTIVE",
            "ACTOR", "ACTUAL", "ADDRESS", "ADMIT", "ADULT", "ADVANCE", "ADVICE", "AFFAIR", "AFFORD", "AFRAID",
            "AFTER", "AGAIN", "AGAINST", "AGENCY", "AGENT", "AGREE", "AHEAD", "ALLOW", "ALMOST", "ALONE",
            "ALONG", "ALREADY", "ALSO", "ALTER", "ALWAYS", "AMOUNT", "ANCIENT", "ANGER", "ANGLE", "ANIMAL",
            "ANNOUNCE", "ANSWER", "ANYBODY", "ANYONE", "ANYTHING", "ANYWAY", "APART", "APPEAR", "APPLY", "APPROACH",
            "AREA", "ARGUE", "AROUND", "ARRIVE", "ARTICLE", "ARTIST", "ASPECT", "ASSUME", "ATTACK", "ATTEMPT", "ATTEND",
            "AUTHOR", "AVERAGE", "AWARE", "BALANCE", "BALL", "BANK", "BASE", "BASIC", "BASIS", "BEACH",
            "BEAR", "BEAT", "BEAUTY", "BECOME", "BEFORE", "BEGIN", "BEHIND", "BELIEF", "BELIEVE", "BENEFIT",
            "BESIDE", "BETTER", "BETWEEN", "BEYOND", "BLACK", "BLOCK", "BLOOD", "BOARD", "BOAST", "BOTTLE",
            "BOTTOM", "BRANCH", "BREAD", "BREAK", "BRIDGE", "BRIGHT", "BRING", "BROTHER", "BUILD", "BURDEN",
            "BUSINESS", "BUTTON", "CAMERA", "CAMPAIGN", "CANCEL", "CANDLE", "CAPITAL", "CAPTAIN", "CAREER", "CASTLE",
            "CATCH", "CENTER", "CENTURY", "CERTAIN", "CHALLENGE", "CHAMBER", "CHANCE", "CHANGE", "CHARGE", "CHARM",
            "CHART", "CHECK", "CHEST", "CHOICE", "CHURCH", "CIRCLE", "CITIZEN", "CLAIM", "CLASS", "CLEAN",
            "CLEAR", "CLIMB", "CLOCK", "CLOSE", "CLOTH", "CLOUD", "COAST", "COLLEGE", "COLOR", "COLUMN",
            "COMBINE", "COMFORT", "COMMAND", "COMMON", "COMPANY", "COMPARE", "COMPETE", "CONCERT", "CONFIRM", "CONNECT",
            "CONSIDER", "CONTROL", "CORNER", "COUNT", "COUNTRY", "COUNTY", "COUPLE", "COURT", "COVER", "CREATE",
            "CREDIT", "CRIME", "CROWD", "CROWN", "CULTURE", "CUSTOM", "DAMAGE", "DANGER", "DARKNESS", "DAUGHTER",
            "DEBATE", "DECIDE", "DECISION", "DEFEND", "DEGREE", "DEMAND", "DEPEND", "DESERT", "DESIGN", "DESIRE",
            "DETAIL", "DEVICE", "DIFFER", "DINNER", "DIRECT", "DISCOVER", "DISCUSS", "DISEASE", "DISPLAY", "DISTANCE",
            "DOCTOR", "DOLLAR", "DOMAIN", "DOUBLE", "DRAGON", "DREAM", "DRIVER", "EARTH", "EASTERN", "ECONOMY",
            "EDITION", "EFFECT", "EFFORT", "EIGHT", "EITHER", "ELECTION", "ELEMENT", "ENERGY", "ENGINE", "ENJOY",
            "ENOUGH", "ENTER", "ENTIRE", "ESCAPE", "ESTATE", "ETHICS", "EVENING", "EVENT", "EVERY", "EXACT",
            "EXAMPLE", "EXPECT", "EXPERT", "EXPLAIN", "EXPORT", "EXPRESS", "FACTOR", "FACTORY", "FAILURE", "FAMILY",
            "FARMER", "FATHER", "FEATURE", "FELLOW", "FIELD", "FIGURE", "FINGER", "FINISH", "FLIGHT", "FLOWER",
            "FOLLOW", "FOREST", "FORGET", "FORMER", "FORWARD", "FRIEND", "FUTURE", "GARDEN", "GATHER", "GENDER",
            "GENERAL", "GENTLE", "GLOBAL", "GOLDEN", "GROUND", "GROWTH", "HANDLE", "HAPPEN", "HARBOR", "HEALTH",
            "HEAVEN", "HEIGHT", "HIDDEN", "HISTORY", "HOLDER", "HONEST", "HONOR", "HOPEFUL", "HOSPITAL", "HOUSE",
            "HUMAN", "HUNGER", "HURRICANE", "HEARING", "IDENTITY", "IMAGINE", "IMPACT", "IMPORT", "IMPROVE", "INCLUDE",
            "INCOME", "INCREASE", "INDEED", "INJURY", "INSIDE", "INSPIRE", "INSTALL", "INTENT", "INVEST", "ISLAND",
            "ITSELF", "JOURNEY", "JUDGMENT", "JUSTICE", "KITCHEN", "KNOWLEDGE", "LABOR", "LANGUAGE", "LAUGHTER", "LEADER",
            "LEAGUE", "LEARN", "LETTER", "LIGHT", "LISTEN", "LITTLE", "LIVING", "LOCATION", "MACHINE", "MAGAZINE",
            "MAINTAIN", "MAJOR", "MANAGE", "MARKET", "MASTER", "MATERIAL", "MATTER", "MAXIMUM", "MEASURE", "MEDICAL",
            "MEMBER", "MEMORY", "MENTAL", "METHOD", "MIDDLE", "MILLION", "MINUTE", "MIRROR", "MISSION", "MODERN",,
            "MOMENT", "MONEY", "MONTH", "MOTHER", "MOTION", "MOUNTAIN", "MOVEMENT", "MUSEUM", "MUSIC", "NATION",
            "NATIVE", "NATURE", "NEIGHBOR", "NETWORK", "NEVER", "NUMBER", "OBJECT", "OBTAIN", "OFFICE", "OFFICER",
            "OPINION", "OPTION", "ORANGE", "ORDER", "ORIGIN", "OUTSIDE", "OWNER", "PARENT", "PARTNER", "PARTY",
            "PASSAGE", "PATIENT", "PATTERN", "PAYMENT", "PEOPLE", "PERFECT", "PERIOD", "PERSON", "PICTURE", "PLANET",
            "PLAYER", "PLEASE", "POCKET", "POLICE", "POLICY", "PORTRAIT", "POSITION", "POSITIVE", "POSSIBLE", "POWER",
            "PRACTICE", "PREPARE", "PRESENT", "PRESIDENT", "PRESS", "PRETTY", "PREVENT", "PRICE", "PRINCE", "PRISON",
            "PRIVATE", "PROBLEM", "PROCESS", "PRODUCE", "PRODUCT", "PROJECT", "PROMISE", "PROTECT", "PROVIDE", "PUBLIC",
            "PURPOSE", "QUALITY", "QUARTER", "QUESTION", "QUICK", "QUIET", "RAISE", "REACH", "REASON", "RECEIVE",
            "RECORD", "REDUCE", "REGION", "RELATE", "RELEASE", "REMAIN", "REMEMBER", "REMOVE", "REPORT", "REQUIRE",,
            "RESULT", "RETURN", "REVEAL", "RIVER", "SAFETY", "SAMPLE", "SCHOOL", "SCIENCE", "SEARCH", "SEASON",
            "SECOND", "SECRET", "SECTION", "SECURE", "SELECT", "SENIOR", "SERIES", "SERIOUS", "SERVICE", "SHADOW",
            "SHARED", "SHELTER", "SHOULDER", "SIGNAL", "SILENT", "SILVER", "SIMPLE", "SINGLE", "SISTER", "SOCIETY",
            "SOURCE", "SPECIAL", "SPIRIT", "SQUARE", "STATION", "STATUS", "STREET", "STRONG", "STUDENT", "SUBJECT",
            "SUCCESS", "SUMMER", "SUPPORT", "SURFACE", "SYSTEM", "TALENT", "TARGET", "TEACHER", "THEORY", "THOUGHT",
            "TIMING", "TRAVEL", "TREATY", "TUNNEL", "UNIQUE", "UNITED", "VALLEY", "VALUE", "VICTORY", "VILLAGE",
            "VISION", "VOICE", "VOLUME", "WINDOW", "WINTER", "WISDOM", "WITHOUT", "WONDER", "WORKER", "YELLOW"
        ];

        // --- APP STATE ---
        let gridSize = 13;
        let starterClueCount = 3;
        let solutionGrid = []; // 2D array of chars
        let numberGrid = [];   // 2D array of assigned numbers 1-26 (0 = black cell)
        let playerGrid = [];   // 2D array of player entered letters
        let letterToNumber = {}; // Map 'A' -> 15
        let numberToLetter = {}; // Map 15 -> 'A'
        let revealedNumbers = new Set();
        let selectedCell = null; // {r, c}

        // --- DOM ELEMENTS ---
        const gridContainer = document.getElementById('grid-container');
        const printGridContainer = document.getElementById('print-grid-container');
        const printSolutionGridContainer = document.getElementById('print-solution-grid-container');
        const numberKeyGrid = document.getElementById('number-key-grid');
        const alphabetBar = document.getElementById('alphabet-bar');
        const completionStatus = document.getElementById('completion-status');

        // --- GENERATOR ALGORITHM ---
        function generatePuzzle() {
            gridSize = parseInt(document.getElementById('grid-size').value);
            starterClueCount = parseInt(document.getElementById('clue-count').value);

            let success = false;
            let attempts = 0;

            while (!success && attempts < 50) {
                attempts++;
                success = tryGenerateGrid();
            }

            if (!success) {
                alert("Failed to build a complete crossword grid. Retrying...");
                generatePuzzle();
                return;
            }

            assignNumbersToLetters();
            selectStarterClues();
            resetPlayerGrid();
            renderAll();
        }

        function tryGenerateGrid() {
            // Initialize empty grid ('.' = black cell)
            solutionGrid = Array(gridSize).fill(null).map(() => Array(gridSize).fill('.'));

            // Sort words by length descending
            const shuffledWords = [...DICTIONARY].sort(() => Math.random() - 0.5);

            // Place first seed word in middle row
            const firstWord = shuffledWords[0];
            const startCol = Math.floor((gridSize - firstWord.length) / 2);
            const midRow = Math.floor(gridSize / 2);

            for (let i = 0; i < firstWord.length; i++) {
                solutionGrid[midRow][startCol + i] = firstWord[i];
            }

            let placedCount = 1;
            
            // Try intersecting subsequent words
            for (let w = 1; w < shuffledWords.length && placedCount < (gridSize * 1.5); w++) {
                const word = shuffledWords[w];
                if (tryPlaceWord(word)) {
                    placedCount++;
                }
            }

            // Verify unique letter count used (Must be at least 18-26 unique letters for a good Codeword puzzle)
            const usedLetters = new Set();
            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    if (solutionGrid[r][c] !== '.') {
                        usedLetters.add(solutionGrid[r][c]);
                    }
                }
            }

            return usedLetters.size >= 16; // Ensure good letter variety
        }

        function tryPlaceWord(word) {
            const directions = ['H', 'V'];
            const shuffledDirs = directions.sort(() => Math.random() - 0.5);

            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    if (solutionGrid[r][c] !== '.') {
                        const char = solutionGrid[r][c];
                        const matchingIndices = [];
                        for (let i = 0; i < word.length; i++) {
                            if (word[i] === char) matchingIndices.push(i);
                        }

                        for (let matchIdx of matchingIndices) {
                            for (let dir of shuffledDirs) {
                                if (canPlace(word, r, c, matchIdx, dir)) {
                                    doPlace(word, r, c, matchIdx, dir);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }

        function canPlace(word, r, c, matchIdx, dir) {
            let startR = dir === 'V' ? r - matchIdx : r;
            let startC = dir === 'H' ? c - matchIdx : c;

            if (startR < 0 || startC < 0) return false;
            if (dir === 'H' && startC + word.length > gridSize) return false;
            if (dir === 'V' && startR + word.length > gridSize) return false;

            // Check boundaries & adjacent collisions
            for (let i = 0; i < word.length; i++) {
                let currR = dir === 'V' ? startR + i : startR;
                let currC = dir === 'H' ? startC + i : startC;

                let existing = solutionGrid[currR][currC];
                if (existing !== '.' && existing !== word[i]) return false;

                // Prevent parallel adjacent words
                if (existing === '.') {
                    if (dir === 'H') {
                        if (currR > 0 && solutionGrid[currR - 1][currC] !== '.') return false;
                        if (currR < gridSize - 1 && solutionGrid[currR + 1][currC] !== '.') return false;
                    } else {
                        if (currC > 0 && solutionGrid[currR][currC - 1] !== '.') return false;
                        if (currC < gridSize - 1 && solutionGrid[currR][currC + 1] !== '.') return false;
                    }
                }
            }

            return true;
        }

        function doPlace(word, r, c, matchIdx, dir) {
            let startR = dir === 'V' ? r - matchIdx : r;
            let startC = dir === 'H' ? c - matchIdx : c;

            for (let i = 0; i < word.length; i++) {
                let currR = dir === 'V' ? startR + i : startR;
                let currC = dir === 'H' ? startC + i : startC;
                solutionGrid[currR][currC] = word[i];
            }
        }

        function assignNumbersToLetters() {
            const usedLetters = Array.from(new Set(solutionGrid.flat().filter(ch => ch !== '.')));
            
            // Randomly shuffle numbers 1-26
            const numbers = Array.from({length: 26}, (_, i) => i + 1).sort(() => Math.random() - 0.5);

            letterToNumber = {};
            numberToLetter = {};

            usedLetters.forEach((letter, index) => {
                const assignedNum = numbers[index];
                letterToNumber[letter] = assignedNum;
                numberToLetter[assignedNum] = letter;
            });

            // Map grid letters to assigned numbers
            numberGrid = solutionGrid.map(row => 
                row.map(cell => cell === '.' ? 0 : letterToNumber[cell])
            );
        }

        function selectStarterClues() {
            revealedNumbers.clear();
            const availableNumbers = Object.keys(numberToLetter);
            
            // Pick N random distinct numbers as starter clues
            while (revealedNumbers.size < starterClueCount && revealedNumbers.size < availableNumbers.length) {
                const randomNum = parseInt(availableNumbers[Math.floor(Math.random() * availableNumbers.length)]);
                revealedNumbers.add(randomNum);
            }
        }

        function resetPlayerGrid() {
            playerGrid = solutionGrid.map((row, r) =>
                row.map((cell, c) => {
                    if (cell === '.') return '.';
                    const num = numberGrid[r][c];
                    return revealedNumbers.has(num) ? numberToLetter[num] : '';
                })
            );
            selectedCell = null;
        }

        // --- RENDERING FUNCTIONS ---
        function renderAll() {
            renderInteractiveGrid();
            renderNumberKeyBar();
            renderAlphabetChecklist();
            renderPrintViews();
        }

        function renderInteractiveGrid() {
            gridContainer.style.gridTemplateColumns = `repeat(${gridSize}, minmax(0, 1fr))`;
            gridContainer.innerHTML = '';

            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    const cellDiv = document.createElement('div');
                    const num = numberGrid[r][c];

                    if (num === 0) {
                        cellDiv.className = 'cell black-cell';
                    } else {
                        const isGiven = revealedNumbers.has(num);
                        cellDiv.className = `cell ${isGiven ? 'given' : ''}`;
                        
                        if (selectedCell && selectedCell.r === r && selectedCell.c === c) {
                            cellDiv.classList.add('selected');
                        } else if (selectedCell && numberGrid[selectedCell.r][selectedCell.c] === num) {
                            cellDiv.classList.add('highlight-same');
                        }

                        // Number corner label
                        const numSpan = document.createElement('span');
                        numSpan.className = 'cell-number';
                        numSpan.textContent = num;
                        cellDiv.appendChild(numSpan);

                        // Letter display
                        const letterSpan = document.createElement('span');
                        letterSpan.className = 'cell-letter';
                        letterSpan.textContent = playerGrid[r][c] || '';
                        cellDiv.appendChild(letterSpan);

                        cellDiv.addEventListener('click', () => {
                            selectedCell = { r, c };
                            renderInteractiveGrid();
                        });
                    }

                    gridContainer.appendChild(cellDiv);
                }
            }
        }

        function renderNumberKeyBar() {
            numberKeyGrid.innerHTML = '';
            let solvedCount = 0;

            for (let num = 1; num <= 26; num++) {
                const targetLetter = numberToLetter[num];
                const keyBox = document.createElement('div');
                keyBox.className = 'flex items-center justify-between p-1.5 border border-slate-200 rounded-md bg-slate-50';

                if (!targetLetter) {
                    // Unused number in this puzzle configuration
                    keyBox.innerHTML = `<span class="font-bold text-slate-400">${num}:</span> <span class="text-slate-300">-</span>`;
                } else {
                    // Check if player has entered a letter for all cells with this number
                    const currentEntered = getPlayerLetterForNumber(num);
                    if (currentEntered) solvedCount++;

                    keyBox.innerHTML = `
                        <span class="font-bold text-indigo-700">${num}:</span>
                        <span class="font-extrabold text-sm ${revealedNumbers.has(num) ? 'text-blue-600' : 'text-slate-800'}">${currentEntered || '_'}</span>
                    `;
                }
                numberKeyGrid.appendChild(keyBox);
            }

            const totalUsed = Object.keys(numberToLetter).length;
            completionStatus.textContent = `${solvedCount} / ${totalUsed} Solved`;
        }

        function renderAlphabetChecklist() {
            alphabetBar.innerHTML = '';
            const usedPlayerLetters = new Set(playerGrid.flat().filter(ch => ch !== '.' && ch !== ''));

            for (let i = 65; i <= 90; i++) {
                const char = String.fromCharCode(i);
                const isUsed = usedPlayerLetters.has(char);

                const badge = document.createElement('div');
                badge.className = `w-7 h-7 flex items-center justify-center rounded font-bold text-xs transition ${
                    isUsed 
                        ? 'bg-slate-300 text-slate-500 line-through opacity-60' 
                        : 'bg-indigo-100 text-indigo-800 hover:bg-indigo-200'
                }`;
                badge.textContent = char;
                alphabetBar.appendChild(badge);
            }
        }

        function renderPrintViews() {
            // Render Worksheet Printable Grid
            renderStaticGrid(printGridContainer, false);
            // Render Solution Printable Grid
            renderStaticGrid(printSolutionGridContainer, true);

            // Render Printable Matrix Key Tables
            renderPrintKeyTable(document.getElementById('print-key-table-1'), false);
            renderPrintKeyTable(document.getElementById('print-key-table-2'), true);
        }

        function renderStaticGrid(container, isSolution) {
            container.innerHTML = '';
            container.style.display = 'grid';
            container.style.gridTemplateColumns = `repeat(${gridSize}, minmax(0, 1fr))`;
            container.className = 'puzzle-grid w-full';

            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    const cellDiv = document.createElement('div');
                    const num = numberGrid[r][c];

                    if (num === 0) {
                        cellDiv.className = 'cell black-cell';
                    } else {
                        cellDiv.className = 'cell';
                        const numSpan = document.createElement('span');
                        numSpan.className = 'cell-number';
                        numSpan.textContent = num;
                        cellDiv.appendChild(numSpan);

                        const letterSpan = document.createElement('span');
                        letterSpan.className = 'cell-letter';

                        if (isSolution) {
                            letterSpan.textContent = solutionGrid[r][c];
                        } else if (revealedNumbers.has(num)) {
                            letterSpan.textContent = numberToLetter[num];
                            cellDiv.classList.add('given');
                        }

                        cellDiv.appendChild(letterSpan);
                    }
                    container.appendChild(cellDiv);
                }
            }
        }

        function renderPrintKeyTable(tableElem, isSolution) {
            tableElem.innerHTML = '';
            
            let row1 = '<tr><td class="bg-slate-100 font-bold">Num</td>';
            let row2 = '<tr><td class="bg-slate-100 font-bold">Letter</td>';

            for (let i = 1; i <= 13; i++) {
                row1 += `<td class="font-bold">${i}</td>`;
                const char = isSolution ? (numberToLetter[i] || '-') : (revealedNumbers.has(i) ? numberToLetter[i] : '');
                row2 += `<td class="font-bold text-sm">${char}</td>`;
            }
            row1 += '</tr>';
            row2 += '</tr>';

            let row3 = '<tr><td class="bg-slate-100 font-bold">Num</td>';
            let row4 = '<tr><td class="bg-slate-100 font-bold">Letter</td>';

            for (let i = 14; i <= 26; i++) {
                row3 += `<td class="font-bold">${i}</td>`;
                const char = isSolution ? (numberToLetter[i] || '-') : (revealedNumbers.has(i) ? numberToLetter[i] : '');
                row4 += `<td class="font-bold text-sm">${char}</td>`;
            }
            row3 += '</tr>';
            row4 += '</tr>';

            tableElem.innerHTML = row1 + row2 + row3 + row4;
        }

        // --- HELPER FUNCTIONS ---
        function getPlayerLetterForNumber(num) {
            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    if (numberGrid[r][c] === num) {
                        return playerGrid[r][c];
                    }
                }
            }
            return '';
        }

        function setPlayerLetterForNumber(num, letter) {
            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    if (numberGrid[r][c] === num && !revealedNumbers.has(num)) {
                        playerGrid[r][c] = letter;
                    }
                }
            }
        }

        // --- KEYBOARD INPUT HANDLING ---
        document.addEventListener('keydown', (e) => {
            if (!selectedCell) return;

            const { r, c } = selectedCell;
            const num = numberGrid[r][c];

            if (num === 0 || revealedNumbers.has(num)) return;

            if (e.key === 'Backspace' || e.key === 'Delete') {
                setPlayerLetterForNumber(num, '');
                renderAll();
            } else if (/^[a-zA-Z]$/.test(e.key)) {
                const char = e.key.toUpperCase();
                setPlayerLetterForNumber(num, char);
                renderAll();
            } else if (e.key === 'ArrowRight' && c < gridSize - 1) {
                selectedCell = { r, c: c + 1 };
                renderInteractiveGrid();
            } else if (e.key === 'ArrowLeft' && c > 0) {
                selectedCell = { r, c: c - 1 };
                renderInteractiveGrid();
            } else if (e.key === 'ArrowDown' && r < gridSize - 1) {
                selectedCell = { r: r + 1, c };
                renderInteractiveGrid();
            } else if (e.key === 'ArrowUp' && r > 0) {
                selectedCell = { r: r - 1, c };
                renderInteractiveGrid();
            }
        });

        // --- EVENT LISTENERS ---
        document.getElementById('btn-generate').addEventListener('click', generatePuzzle);
        document.getElementById('btn-print').addEventListener('click', () => window.print());

        document.getElementById('btn-check').addEventListener('click', () => {
            let errorsFound = false;
            for (let r = 0; r < gridSize; r++) {
                for (let c = 0; c < gridSize; c++) {
                    if (playerGrid[r][c] !== '' && playerGrid[r][c] !== solutionGrid[r][c]) {
                        errorsFound = true;
                    }
                }
            }
            alert(errorsFound ? "Some entries are incorrect. Keep trying!" : "Looking good! All entered letters are correct so far.");
        });

        document.getElementById('btn-reveal').addEventListener('click', () => {
            playerGrid = solutionGrid.map(row => [...row]);
            renderAll();
        });

        document.getElementById('btn-reset').addEventListener('click', () => {
            resetPlayerGrid();
            renderAll();
        });

        // Initialize on Load
        window.onload = () => {
            generatePuzzle();
        };
    </script>
</body>
</html>